package woaini.fenger.core.bot.event;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.*;
import woaini.fenger.core.bot.event.Segment;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson2.reader.ObjectReader;
import com.alibaba.fastjson2.writer.ObjectWriter;
import lombok.Data;
import woaini.fenger.core.bot.event.message.impl.*;
import woaini.fenger.core.bot.event.message.impl.Record;
import woaini.fenger.core.bot.id.ID;

/**
 * 消息段封装格式
 *
 * @see Messages
 * @author yefeng {@code @Date} 2023-05-16 16:50:39
 */
@Data
public class Messages {

  /**
   * @see String 原始字符串 CQ 码标识
   */
  private String content;
  /**
   * @see List<Segment> 元素
   */
  private List<Segment> elements;

  public Messages() {
    this.elements = new ArrayList<>();
  }

  public static Messages builder() {
    return new Messages();
  }

  /**
   * @MethodName isAt
   *
   * @author yefeng {@date 2024-01-18 17:08:56}
   * @since 1.0
   * @return {@link Boolean } 获取是否at
   */
  public Boolean isAt(ID id) {
    return this.elements.stream().anyMatch(d -> d instanceof At && ((At) d).getData().getQq().equals(id));
  }

  /**
   * @MethodName actualText
   *
   * @author yefeng {@date 2024-01-18 17:09:15}
   * @since 1.0
   * @return {@link String } 实际文本 仅获取文本只
   */
  public String actualText() {
    Segment text = this.elements.stream().filter(d -> d.getType().equals("text")).findFirst().orElse(null);
    if (text != null) {
      return ((Text)text).getData().getText();
    }
    return null;
  }

  /**
   * @MethodName add
   *
   * @param segment 消息段
   * @author yefeng {@date 2024-01-18 09:55:31}
   * @since 1.0
   * @return {@link Messages } 添加
   */
  public Messages add(Segment segment) {
    this.elements.add(segment);
    return this;
  }

  /**
   * @MethodName at
   *
   * @param id id对应平台
   * @author yefeng {@date 2024-01-18 09:57:06}
   * @since 1.0
   * @return {@link Messages } at某人
   */
  public Messages at(ID id) {
    return this.add(new At(id));
  }

  /**
   * @MethodName face
   *
   * @param id ID
   * @author yefeng {@date 2024-01-18 09:58:48}
   * @since 1.0
   * @return {@link Messages } qq表情
   */
  public Messages face(String id) {
    return this.add(new Face(id));
  }

  /**
   * @MethodName image
   *
   * @param file 文件
   * @author yefeng {@date 2024-01-18 09:59:20}
   * @since 1.0
   * @return {@link Messages } 发送图片信息
   */
  public Messages image(String file) {
    return this.add(new Image(file));
  }

  /**
   * @MethodName record
   *
   * @param file 文件
   * @author yefeng {@date 2024-01-18 09:59:53}
   * @since 1.0
   * @return {@link Messages } 语音信箱
   */
  public Messages record(String file) {
    return this.add(new Record(file));
  }

  /**
   * @MethodName video
   *
   * @param file 文件
   * @author yefeng {@date 2024-01-18 10:00:15}
   * @since 1.0
   * @return {@link Messages } 视频信息
   */
  public Messages video(String file) {
    return this.add(new Video(file));
  }

  /**
   * @MethodName text
   *
   * @param text 文本
   * @author yefeng {@date 2024-01-18 10:00:42}
   * @since 1.0
   * @return {@link Messages } 文本
   */
  public Messages text(String text) {
    return this.add(new Text(text));
  }
  public Messages text(CharSequence template, Object... params) {
    String text = StrUtil.format(template,params);
    return this.add(new Text(text));
  }

  public static class Deserializer implements ObjectReader<Messages> {
    @Override
    public Messages readObject(JSONReader jsonReader, Type fieldType, Object o, long l) {
      if (jsonReader.nextIfNull()) {
        return null;
      }

      Messages messages = new Messages();
      //消息段序列化
      ArrayList<Segment> segments = new ArrayList<>();
      JSONArray parameters = jsonReader.read(JSONArray.class);
      for (int i = 0; i < parameters.size(); i++) {
        JSONObject jsonObject = parameters.getJSONObject(i);
        String typeString = jsonObject.getString("type");
        if (typeString.equals("text")){
          Text text = jsonObject.toJavaObject(Text.class);
          segments.add(text);
        }
      }
      messages.setElements(segments);
      return messages;
    }
  }

  public static class Serializer implements ObjectWriter<Messages> {
    @Override
    public void write(JSONWriter jsonWriter, Object o, Object o1, Type type, long l) {
      Messages messages = (Messages) o;
      jsonWriter.write(messages.getElements());
    }
  }
}
